package me.w70.bot;

import java.awt.image.BufferedImage;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JFrame;
import javax.swing.UIManager;

import me.w70.bot.account.Account;
import me.w70.bot.account.AccountHandler;
import me.w70.bot.events.EventCaster;
import me.w70.bot.gui.MainWindow;
import me.w70.bot.methods.BotGraphics;
import me.w70.bot.methods.Methods;
import me.w70.bot.scripting.Random;
import me.w70.bot.scripting.RandomChecker;
import me.w70.bot.scripting.Script;
import me.w70.bot.scripting.ScriptLoader;
import me.w70.bot.util.Output;

import org.jvnet.substance.skin.SubstanceRavenGraphiteGlassLookAndFeel;

public class Bot {
	public static MainWindow gui;

	public static Output output;

	public static AccountHandler accountHandler;

	public static BufferedImage currentScreen;

	public static Methods methods;

	private static Bot singleton;

	public static RandomChecker randomChecker = new RandomChecker();

	public static boolean allowInput = true;

	public static String SCRIPT_DIR = "./scripts/";

	public static String RANDOM_DIR = "./randoms/";

	public static String CONFIG_DIR = "./config/";

	public static String IMG_DIR = "./imgs/";
	
	public static String PASSIVE_DIR = "./passive/";
	
	public static String SCRIPT_IMG_DIR = "./imgs/script_made/";

	public static BotGraphics painter = new BotGraphics();

	public static ScriptLoader scriptLoader = new ScriptLoader();

	private EventCaster eventCaster;

	private static Account currentAccount = new Account("", "");

	public static void main(String[] args) {
		JFrame.setDefaultLookAndFeelDecorated(true);
		try {
			UIManager
					.setLookAndFeel(new SubstanceRavenGraphiteGlassLookAndFeel());
		} catch (Exception e) {
			System.out.println("Theme failed to initialize");
		}
		new Bot();
	}

	public static Account getCurrentAccount() {
		return currentAccount;
	}
	
	public static void setCurrentAccount(Account a ) { 
		Bot.gui.frame.setTitle(a.getUsername() + " - W70Bot");
		currentAccount = a;
	}

	public static boolean isRandomRunning() {
		for (Random r : Bot.scriptLoader.getLoadedRandoms().values()) {
			if (r.running) {
				System.out.println(r.getScriptName() + " is running");
				return true;
			}
		}
		return false;
	}

	public static Bot getSelf() {
		return singleton;
	}
	public static Logger log = Logger.getLogger(Bot.class.getName());
	public static void addMessage(Class from, Object message) {
		Bot.output.addMessage(from, message, false);
		log.log(Level.INFO, message.toString(), from.toString());
	}

	public static void addMessage(Object from, Object message) {
		addMessage(from.getClass(), message);
	}

	/* TODO Move to appropriate location */
	public static String throwableToString(final Throwable t) {
		if (t == null) {
			return "";
		}
		final Writer exception = new StringWriter();
		final PrintWriter printWriter = new PrintWriter(exception);
		t.printStackTrace(printWriter);
		return exception.toString();
	}
	
	public static void addWarning(Object from, Object message) {
		Bot.output.addMessage(from.getClass(), message, true);
		log.log(Level.WARNING, message.toString(),from);
	}
	
	public static void runScript(String name) {
		Bot.scriptLoader.runScript(name);
	}

	public static void reloadScripts() {

	}

	public static void stopScripts() {
		Bot.scriptLoader.stopScripts();

	}

	public static void togglePauseScripts() {
		Bot.scriptLoader.togglePauseScripts();

	}

	public static Script[] getRunningScripts() {
		Script[] scripts = new Script[Bot.scriptLoader.getLoadedScripts()
				.size()];
		int i = 0;
		for (Script s : Bot.scriptLoader.getLoadedScripts().values()) {
			scripts[i] = s;
			i++;
		}
		return scripts;
	}

	public static Script[] getLoadedScripts() {
		Script[] scripts = new Script[Bot.scriptLoader.getAllLoadedScripts()
				.size()];
		int i = 0;
		for (Script s : Bot.scriptLoader.getAllLoadedScripts().values()) {
			scripts[i] = s;
			i++;
		}
		return scripts;
	}
	
	public static Script[] getLoadedScriptsNoDebug() {
		int sc = Bot.scriptLoader.getAllLoadedScripts().size();
		for (Script s : Bot.scriptLoader.getAllLoadedScripts().values()) {
			if(s.getScriptCategory().equalsIgnoreCase("Debug")) {
				sc--;
			}
		}
		Script[] scripts = new Script[sc];
		int i = 0;
		for (Script s : Bot.scriptLoader.getAllLoadedScripts().values()) {
			if(!s.getScriptCategory().equalsIgnoreCase("Debug")) {
			scripts[i] = s;
			i++;
			}
		}
		return scripts;
	}

	public Bot() {

		Bot.output = new Output();

		Bot.accountHandler = new AccountHandler();
		scriptLoader.loadScripts();
		scriptLoader.loadPassive();
		eventCaster = new EventCaster(this);

		Bot.gui = new MainWindow();

		Bot.addWarning(this, "test");
		Bot.methods = new Methods();
		singleton = this;

		Bot.scriptLoader.loadRandoms();
		Bot.randomChecker.start();
	
		
	}

	public static HashMap<String, Account> getAccounts() {
		return Bot.accountHandler.getAccounts();
	}

	public EventCaster getEventCaster() {
		return eventCaster;
	}

}
